<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  
  <meta name="generator" content="Hugo 0.98.0" />

  
  <meta name="description" content="走在通往幸福的路上">
  

  
  <link rel="apple-touch-icon" sizes="180x180" href="https://blog.v5u.win/apple-touch-icon.png">

  
  <link rel="icon" type="image/png" sizes="32x32" href="https://blog.v5u.win/favicon-32x32.png">

  
  <link rel="icon" type="image/png" sizes="16x16" href="https://blog.v5u.win/favicon-16x16.png">

  
  <link rel="manifest" href="https://blog.v5u.win/site.webmanifest">

  
  <link rel="mask-icon" href="https://blog.v5u.win/safari-pinned-tab.svg" color="">

  <meta name="msapplication-TileColor" content="">

  <meta name="theme-color" content="">

  
  <link rel="stylesheet" href="https://blog.v5u.win/css/bootstrap.min.css" />

  
  <title>WKWebView | 为吾优</title>
  

  <style>
body {
  min-width: 300px;
}

.custom-navbar {
  margin-bottom: 1em;
  height: 60px;
}

.custom-navbar a {
  display: inline-block; 
  padding: 18px 0;
  margin-right: 1em; 
  font-weight: bold; 
}

.custom-navbar a:hover,
.custom-navbar a:focus {
  text-decoration: none; 
}

@media print {
  .custom-navbar {
    display: none;
  }
}

article {
  padding-bottom: 1em;
}

img {
  max-width: 100%;
}


body {
  background-color: #fff;
}



body {
  color: #212529;
}



a {
  color: #007bff;
}



a:hover,
a:focus {
  color: #0056b3;
}



.custom-navbar {
  background-color: #212529;
}



.custom-navbar a {
  color: rgba(255,255,255,.75);
}



.custom-navbar a:hover,
.custom-navbar a:focus {
  color: rgba(255,255,255,1);
}



.container {
  max-width: 800px;
}





</style>
</head>

<body>
  <nav class="custom-navbar">
  <div class="container">
    
    <a href="/">文章</a>
    
    <a href="/tags/">标签</a>
    
    <a href="/about/">关于</a>
    
    <a href="/index.xml">RSS</a>
    
  </div>
</nav>
  
  <div class="container">
    <article>
      <h1>WKWebView</h1>
<p>WKWebView是获取不到JSContext的，所以不能用JavaScriptCore进行交互。和js交互要用WKScriptMessageHandler协议方法</p>
<p>//MARK: - WKNavigationDelegate</p>
<p>//该代理提供的方法，可以用来追踪加载过程（页面开始加载、加载完成、加载失败）、决定是否执行跳转</p>
<p>// 页面跳转的代理方法有三种，分为（收到跳转与决定是否跳转两种）</p>
<p>// 剩下三个代理方法全都是与界面弹出提示框相关的</p>
<p>// 针对于web界面的三种提示框（警告框、确认框、输入框）分别对应三种代理方法。</p>
<p>//MARK: - WKScriptMessageHandler</p>
<p>//这个协议中包含一个必须实现的方法，这个方法是提高App与web端交互的关键，它可以直接将接收到的JS脚本转为OC或Swift对象。（当然，在UIWebView也可以通过“曲线救国”的方式与web进行交互，著名的Cordova框架就是这种机制</p>
<p>// 处理来自js的方法调用</p>
<p>// 从web界面中接收到一个脚本时调用 js端的写法：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#75715e">// postMessage 参数不能为空，必须传点什么
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 格式为 window.webkit.messageHandlers..postMessage(null);
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 外部方法必须为 全局js方法
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">scanClick</span>() {
</span></span><span style="display:flex;"><span>    window.<span style="color:#a6e22e">webkit</span>.<span style="color:#a6e22e">messageHandlers</span>.<span style="color:#a6e22e">ScanAction</span>.<span style="color:#a6e22e">postMessage</span>(<span style="color:#66d9ef">null</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>OC端的写法：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-objective-c" data-lang="objective-c"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 在某一个地方注册
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>[self.webView.configuration.userContentController addScriptMessageHandler:self name:<span style="color:#e6db74">@&#34;ScanAction&#34;</span>];
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 在某一个地方移除
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>[self.webView.configuration.userContentController removeScriptMessageHandlerForName:<span style="color:#e6db74">@&#34;ScanAction&#34;</span>];
</span></span><span style="display:flex;"><span><span style="color:#75715e">//MARK: - WKScriptMessageHandler 代理方法的实现
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">userContentController:</span>(WKUserContentController <span style="color:#f92672">*</span>)userContentController <span style="color:#a6e22e">didReceiveScriptMessage:</span>(WKScriptMessage <span style="color:#f92672">*</span>)message{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ([message.name isEqualToString:<span style="color:#e6db74">@&#34;ScanAction&#34;</span>]) {
</span></span><span style="display:flex;"><span>           NSLog(<span style="color:#e6db74">@&#34;说吧，你想干点什么？&#34;</span>);
</span></span><span style="display:flex;"><span>       }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-objective-c" data-lang="objective-c"><span style="display:flex;"><span><span style="color:#75715e">//
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">//  WKWebViewController.m
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">//  HTML_CSS_JS
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">//
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">//  Created by 范金龙 on 2020/4/28.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">//  Copyright © 2020 FF. All rights reserved.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">//
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#75715e">#import &#34;WKWebViewController.h&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">#import 
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">#import 
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">#import &#34;WKDelegate.h&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">@interface</span> <span style="color:#a6e22e">WKWebViewController</span> ()
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;</span>
</span></span><span style="display:flex;"><span>WKNavigationDelegate,
</span></span><span style="display:flex;"><span>WKUIDelegate,
</span></span><span style="display:flex;"><span>WKScriptMessageHandler
</span></span><span style="display:flex;"><span><span style="color:#75715e">//WKDelegate
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">@property</span> (<span style="color:#66d9ef">nonatomic</span>, <span style="color:#66d9ef">strong</span>)WKWebView <span style="color:#f92672">*</span>webView;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">@end</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">@implementation</span> <span style="color:#a6e22e">WKWebViewController</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> NSString <span style="color:#f92672">*</span>name <span style="color:#f92672">=</span> <span style="color:#e6db74">@&#34;OCFunc&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 避免循环引用，内存管理，这是一个经典的大环引用问题。
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 具体解决方案有好几种，比如：中间类，间接代理，提前手动删除打断。
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// addScriptMessageHandler 会强引用self导致当前对象无法释放
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">viewWillAppear:</span>(<span style="color:#66d9ef">BOOL</span>)animated{
</span></span><span style="display:flex;"><span>    [super viewWillAppear:animated];
</span></span><span style="display:flex;"><span>    [self.webView.configuration.userContentController addScriptMessageHandler:self name:<span style="color:#e6db74">@&#34;toServer&#34;</span>];
</span></span><span style="display:flex;"><span>    [self.webView.configuration.userContentController addScriptMessageHandler:self name:<span style="color:#e6db74">@&#34;ScanAction&#34;</span>];
</span></span><span style="display:flex;"><span>    [self.webView.configuration.userContentController addScriptMessageHandler:self name:name];
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">viewWillDisappear:</span>(<span style="color:#66d9ef">BOOL</span>)animated{
</span></span><span style="display:flex;"><span>    [super viewWillDisappear:animated];
</span></span><span style="display:flex;"><span>    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:<span style="color:#e6db74">@&#34;toServer&#34;</span>];
</span></span><span style="display:flex;"><span>    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:<span style="color:#e6db74">@&#34;ScanAction&#34;</span>];
</span></span><span style="display:flex;"><span>    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:name];
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">viewDidLoad</span> {
</span></span><span style="display:flex;"><span>    [super viewDidLoad];
</span></span><span style="display:flex;"><span>    [self.view setBackgroundColor:[UIColor whiteColor]];
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Do any additional setup after loading the view.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    [self initWKWebView];
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">initWKWebView</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    WKWebViewConfiguration <span style="color:#f92672">*</span>configuration <span style="color:#f92672">=</span> [[WKWebViewConfiguration alloc] init];
</span></span><span style="display:flex;"><span>    WKPreferences <span style="color:#f92672">*</span>preferences <span style="color:#f92672">=</span> [WKPreferences new];
</span></span><span style="display:flex;"><span>    preferences.javaScriptCanOpenWindowsAutomatically <span style="color:#f92672">=</span> YES;
</span></span><span style="display:flex;"><span>    preferences.minimumFontSize <span style="color:#f92672">=</span> <span style="color:#ae81ff">10.0</span>;
</span></span><span style="display:flex;"><span>    configuration.preferences <span style="color:#f92672">=</span> preferences;
</span></span><span style="display:flex;"><span>    self.webView <span style="color:#f92672">=</span> [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
</span></span><span style="display:flex;"><span>    NSString <span style="color:#f92672">*</span>urlStr <span style="color:#f92672">=</span> [[NSBundle mainBundle] pathForResource:<span style="color:#e6db74">@&#34;wkDemo.html&#34;</span> ofType:nil];
</span></span><span style="display:flex;"><span>    NSURL <span style="color:#f92672">*</span>fileURL <span style="color:#f92672">=</span> [NSURL fileURLWithPath:urlStr];
</span></span><span style="display:flex;"><span>    [self.webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];
</span></span><span style="display:flex;"><span>    self.webView.UIDelegate <span style="color:#f92672">=</span> self;
</span></span><span style="display:flex;"><span>    [self.view addSubview:self.webView];
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">//MARK: WKNavigationDelegate
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">//该代理提供的方法，可以用来追踪加载过程（页面开始加载、加载完成、加载失败）、决定是否执行跳转
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 页面开始加载时调用
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">didStartProvisionalNavigation:</span>(WKNavigation <span style="color:#f92672">*</span>)navigation{
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 当内容开始返回时调用
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">didCommitNavigation:</span>(WKNavigation <span style="color:#f92672">*</span>)navigation{
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 页面加载完成之后调用
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">didFinishNavigation:</span>(WKNavigation <span style="color:#f92672">*</span>)navigation{
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">//向js注入关闭按钮事件监听
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    NSString <span style="color:#f92672">*</span>script <span style="color:#f92672">=</span> <span style="color:#e6db74">@&#34;document.querySelector(&#39;.close-btn&#39;).addEventListener(&#39;click&#39;,function() {window.webkit.messageHandlers.toServer.postMessage(&#39;close&#39;)},false)&#34;</span>;
</span></span><span style="display:flex;"><span>    [webView evaluateJavaScript:script completionHandler:<span style="color:#f92672">^</span>(<span style="color:#66d9ef">id</span> object, NSError <span style="color:#f92672">*</span> _Nullable error) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span>(error){
</span></span><span style="display:flex;"><span>            NSLog(<span style="color:#e6db74">@&#34;evaluateJavaScript error : %@&#34;</span>,error);
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }];
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 页面加载失败时调用
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">didFailProvisionalNavigation:</span>(WKNavigation <span style="color:#f92672">*</span>)navigation{
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">// MARK:-
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 页面跳转的代理方法有三种，分为（收到跳转与决定是否跳转两种）
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 接收到服务器跳转请求之后调用
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">didReceiveServerRedirectForProvisionalNavigation:</span>(WKNavigation <span style="color:#f92672">*</span>)navigation{
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 在收到响应后，决定是否跳转
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">decidePolicyForNavigationResponse:</span>(WKNavigationResponse <span style="color:#f92672">*</span>)navigationResponse <span style="color:#a6e22e">decisionHandler:</span>(<span style="color:#66d9ef">void</span> (<span style="color:#f92672">^</span>)(WKNavigationResponsePolicy))decisionHandler{
</span></span><span style="display:flex;"><span>    decisionHandler(WKNavigationResponsePolicyAllow);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 在发送请求之前，决定是否跳转
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">decidePolicyForNavigationAction:</span>(nonnull WKNavigationAction <span style="color:#f92672">*</span>)navigationAction <span style="color:#a6e22e">decisionHandler:</span>(nonnull <span style="color:#66d9ef">void</span> (<span style="color:#f92672">^</span>)(WKNavigationActionPolicy))decisionHandler{
</span></span><span style="display:flex;"><span>    decisionHandler(WKNavigationActionPolicyAllow);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">//MARK: WKUIDelegate
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 创建一个新的WebView 待研究
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (WKWebView <span style="color:#f92672">*</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">createWebViewWithConfiguration:</span>(WKWebViewConfiguration <span style="color:#f92672">*</span>)configuration <span style="color:#a6e22e">forNavigationAction:</span>(WKNavigationAction <span style="color:#f92672">*</span>)navigationAction <span style="color:#a6e22e">windowFeatures:</span>(WKWindowFeatures <span style="color:#f92672">*</span>)windowFeatures{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> self.webView;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">//MARK:- 剩下三个代理方法全都是与界面弹出提示框相关的
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">//针对于web界面的三种提示框（警告框、确认框、输入框）分别对应三种代理方法。下面只举了警告框的例子。
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#75715e">/**
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *  web界面中有弹出警告框时调用
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *  @param webView           实现该代理的webview
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *  @param message           警告框中的内容
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *  @param frame             主窗口
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *  @param completionHandler 警告框消失调用
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> */</span>
</span></span><span style="display:flex;"><span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">runJavaScriptAlertPanelWithMessage:</span>(nonnull NSString <span style="color:#f92672">*</span>)message <span style="color:#a6e22e">initiatedByFrame:</span>(nonnull WKFrameInfo <span style="color:#f92672">*</span>)frame <span style="color:#a6e22e">completionHandler:</span>(nonnull <span style="color:#66d9ef">void</span> (<span style="color:#f92672">^</span>)(<span style="color:#66d9ef">void</span>))completionHandler
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span><span style="color:#75715e">//    js 调用的alert方法，被wk拦截，在此处执行
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    completionHandler();
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">runJavaScriptConfirmPanelWithMessage:</span>(NSString <span style="color:#f92672">*</span>)message <span style="color:#a6e22e">initiatedByFrame:</span>(WKFrameInfo <span style="color:#f92672">*</span>)frame <span style="color:#a6e22e">completionHandler:</span>(<span style="color:#66d9ef">void</span> (<span style="color:#f92672">^</span>)(<span style="color:#66d9ef">BOOL</span>))completionHandler{completionHandler(true);}
</span></span><span style="display:flex;"><span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">webView:</span>(WKWebView <span style="color:#f92672">*</span>)webView <span style="color:#a6e22e">runJavaScriptTextInputPanelWithPrompt:</span>(NSString <span style="color:#f92672">*</span>)prompt <span style="color:#a6e22e">defaultText:</span>(NSString <span style="color:#f92672">*</span>)defaultText <span style="color:#a6e22e">initiatedByFrame:</span>(WKFrameInfo <span style="color:#f92672">*</span>)frame <span style="color:#a6e22e">completionHandler:</span>(<span style="color:#66d9ef">void</span> (<span style="color:#f92672">^</span>)(NSString <span style="color:#f92672">*</span> _Nullable))completionHandler{    completionHandler(<span style="color:#e6db74">@&#34;输入&#34;</span>);}
</span></span><span style="display:flex;"><span><span style="color:#75715e">//MARK: WKScriptMessageHandler
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">//这个协议中包含一个必须实现的方法，这个方法是提高App与web端交互的关键，它可以直接将接收到的JS脚本转为OC或Swift对象。（当然，在UIWebView也可以通过“曲线救国”的方式与web进行交互，著名的Cordova框架就是这种机制
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 处理来自js的方法调用
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// 从web界面中接收到一个脚本时调用
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">userContentController:</span>(WKUserContentController <span style="color:#f92672">*</span>)userContentController <span style="color:#a6e22e">didReceiveScriptMessage:</span>(WKScriptMessage <span style="color:#f92672">*</span>)message{
</span></span><span style="display:flex;"><span>    NSLog(<span style="color:#e6db74">@&#34;%@&#34;</span>,message.name);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ([message.name isEqualToString:<span style="color:#e6db74">@&#34;ScanAction&#34;</span>]) {
</span></span><span style="display:flex;"><span>           NSLog(<span style="color:#e6db74">@&#34;扫一扫&#34;</span>);
</span></span><span style="display:flex;"><span>       }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ([message.name isEqualToString:<span style="color:#e6db74">@&#34;OCFunc&#34;</span>]){<span style="color:#75715e">//此处name为JS传出信息打包的标志
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">//用message.body获得JS传出的参数体
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">//handle coding..
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">/*获得传出的字符串参数*/</span>
</span></span><span style="display:flex;"><span>        NSString <span style="color:#f92672">*</span> dataString <span style="color:#f92672">=</span> message.body;
</span></span><span style="display:flex;"><span>        NSLog(<span style="color:#e6db74">@&#34;wkwebview 获取js传出的数据%@&#34;</span>,dataString);
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// 在需要调用JS的地方执行如下代码
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">// 有参数
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        [self.webView evaluateJavaScript:<span style="color:#e6db74">@&#34;postInfo(&#39;参数1,参数2&#39;)&#34;</span>completionHandler:nil];
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// 无参数
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        [self.webView evaluateJavaScript:<span style="color:#e6db74">@&#34;postInfo()&#34;</span>completionHandler:nil];
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// 此处的 &#39;postInfo()&#39; 是前端的方法，需要前端告诉你
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>- (<span style="color:#66d9ef">void</span>)<span style="color:#a6e22e">dealloc</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    NSLog(<span style="color:#e6db74">@&#34;%s&#34;</span>,__FUNCTION__);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">@end</span>
</span></span></code></pre></div><p>wkDemo.html 实例HTML的代码如下</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-swift" data-lang="swift"><span style="display:flex;"><span>            function scanClick() {
</span></span><span style="display:flex;"><span>                window.webkit.messageHandlers.ScanAction.postMessage(null);
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// &lt;!-- 错误处理 --&gt;</span>
</span></span><span style="display:flex;"><span>            window.onerror = function(err) {
</span></span><span style="display:flex;"><span>                log(<span style="color:#960050;background-color:#1e0010">&#39;</span>window.onerror: <span style="color:#960050;background-color:#1e0010">&#39;</span> <span style="color:#f92672">+</span> err)
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>            function log(message, data) {
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">var</span> log = document.getElementById(<span style="color:#960050;background-color:#1e0010">&#39;</span>log<span style="color:#960050;background-color:#1e0010">&#39;</span>)
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">var</span> el = document.createElement(<span style="color:#960050;background-color:#1e0010">&#39;</span>p<span style="color:#960050;background-color:#1e0010">&#39;</span>)
</span></span><span style="display:flex;"><span>                el.className = <span style="color:#960050;background-color:#1e0010">&#39;</span>logLine<span style="color:#960050;background-color:#1e0010">&#39;</span>
</span></span><span style="display:flex;"><span>                el.innerHTML = <span style="color:#e6db74">&#34;message: &#34;</span> <span style="color:#f92672">+</span> message <span style="color:#f92672">+</span><span style="color:#960050;background-color:#1e0010">&#39;</span>:&lt;br<span style="color:#f92672">/&gt;</span><span style="color:#960050;background-color:#1e0010">&#39;</span> <span style="color:#f92672">+</span> (data ? <span style="color:#960050;background-color:#1e0010">&#39;</span>:&lt;br<span style="color:#f92672">/&gt;</span><span style="color:#960050;background-color:#1e0010">&#39;</span> <span style="color:#f92672">+</span> JSON.stringify(data) : <span style="color:#960050;background-color:#1e0010">&#39;&#39;</span>)
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">if</span> (log.children.length) { log.insertBefore(el, log.children[<span style="color:#ae81ff">0</span>]) }
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">else</span> { log.appendChild(el) }
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// function buttonOnClick = function (e) {} // 这种写法有问题,WKWebView 捕获的js方法必须为全局方法，也不可以是方法变量。</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// 下面这种形式正确</span>
</span></span><span style="display:flex;"><span>            function buttonOnClick(e) {
</span></span><span style="display:flex;"><span>                window.webkit.messageHandlers.OCFunc.postMessage(<span style="color:#960050;background-color:#1e0010">&#39;</span>close<span style="color:#960050;background-color:#1e0010">&#39;</span>)<span style="color:#75715e">//调用原生代码</span>
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>            function postInfo(name) {
</span></span><span style="display:flex;"><span>                log(name)
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> 
</span></span><span style="display:flex;"><span>            html { font<span style="color:#f92672">-</span>family:Helvetica; color:#ddd; }
</span></span><span style="display:flex;"><span>            h1 { color:steelblue; font<span style="color:#f92672">-</span>size:<span style="color:#ae81ff">24</span>pm; margin<span style="color:#f92672">-</span>top:<span style="color:#ae81ff">24</span>px; }
</span></span><span style="display:flex;"><span>            button { margin:<span style="color:#ae81ff">0</span> <span style="color:#ae81ff">3</span>px <span style="color:#ae81ff">10</span>px; font<span style="color:#f92672">-</span>size:<span style="color:#ae81ff">2</span>pm; }
</span></span><span style="display:flex;"><span>            .logLine { border<span style="color:#f92672">-</span>bottom:<span style="color:#ae81ff">1</span>px solid #ccc; padding:<span style="color:#ae81ff">4</span>px <span style="color:#ae81ff">2</span>px; font<span style="color:#f92672">-</span>family:courier; font<span style="color:#f92672">-</span>size:<span style="color:#ae81ff">11</span>pm; }
</span></span><span style="display:flex;"><span>            div{color: black;line<span style="color:#f92672">-</span>height:<span style="color:#ae81ff">100</span><span style="color:#f92672">%</span>;border<span style="color:#f92672">-</span>color: #ccc; border<span style="color:#f92672">-</span>width:<span style="color:#ae81ff">1</span>px;}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        WebViewJavascriptBridge Demo
</span></span><span style="display:flex;"><span>        
</span></span><span style="display:flex;"><span>        buttons
</span></span><span style="display:flex;"><span>            
</span></span><span style="display:flex;"><span>            alert
</span></span><span style="display:flex;"><span>            OC注入
</span></span><span style="display:flex;"><span>            js <span style="color:#960050;background-color:#1e0010">调用</span>Native方法
</span></span><span style="display:flex;"><span>        
</span></span><span style="display:flex;"><span>        log
</span></span></code></pre></div>
    </article>
  </div>

  
  
  

  
</body>

</html>